<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" >

<title>iOS11下的适配工作 | 迷航</title>
<meta name="description" content="人可以迷失方向，但是不能停下脚步！">

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="shortcut icon" href="https://tingke.gitee.io/post/favicon.ico?v=1690805106645">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.10.0/katex.min.css">
<link rel="stylesheet" href="https://tingke.gitee.io/post/styles/main.css">



<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js"></script>

<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />



  </head>
  <body>
    <div id="app" class="main">

      <div class="sidebar" :class="{ 'full-height': menuVisible }">
  <div class="top-container" data-aos="fade-right">
    <div class="top-header-container">
      <a class="site-title-container" href="https://tingke.gitee.io/post">
        <img src="https://tingke.gitee.io/post/images/avatar.png?v=1690805106645" class="site-logo">
        <h1 class="site-title">迷航</h1>
      </a>
      <div class="menu-btn" @click="menuVisible = !menuVisible">
        <div class="line"></div>
      </div>
    </div>
    <div>
      
        
          <a href="/" class="site-nav">
            首页
          </a>
        
      
        
          <a href="/archives" class="site-nav">
            归档
          </a>
        
      
        
          <a href="/tags" class="site-nav">
            标签
          </a>
        
      
        
          <a href="/post/about" class="site-nav">
            关于
          </a>
        
      
    </div>
  </div>
  <div class="bottom-container" data-aos="flip-up" data-aos-offset="0">
    <div class="social-container">
      
        
      
        
      
        
      
        
      
        
      
    </div>
    <div class="site-description">
      人可以迷失方向，但是不能停下脚步！
    </div>
    <div class="site-footer">
      Powered by <a href="https://github.com/getgridea/gridea" target="_blank">Gridea</a> Copyright © 2019 | <a class="rss" href="https://tingke.gitee.io/post/atom.xml" target="_blank">RSS</a>
    </div>
  </div>
</div>


      <div class="main-container">
        <div class="content-container" data-aos="fade-up">
          <div class="post-detail">
            <h2 class="post-title">iOS11下的适配工作</h2>
            <div class="post-date">2017-10-13</div>
            
            <div class="post-content">
              <blockquote>
<p>今年的苹果，发布iOS 11的同时，也大胆的发布了异型屏iPhone X。独特的“刘海”造型又在手机样式方面独领风骚。但是这也为iOS开发工作增加了难度。</p>
</blockquote>
<!-- more -->
<p>iPhone X的屏幕尺寸相关变化</p>
<ol>
<li>高度增加了145pt，变成812pt.</li>
<li>屏幕圆角显示，注意至少留10pt边距。</li>
<li>状态栏高度由20pt变成44pt，留意这个距离就能避开“刘海”的尴尬，相应的导航栏以上变化64-&gt;88。</li>
<li>底部工具栏需要为home indicator留出34pt边距。</li>
<li>物理分辨率为1125px * 2436px，使用@3倍图</li>
</ol>
<p>本次系统升级带来了以下内容：</p>
<ol>
<li>集成了搜索的大标题栏</li>
<li>提倡在安全区域内布局</li>
<li>导航栏的titleView支持自动布局</li>
<li>废除了xxx，新增了xxx</li>
<li>App中必须添加 1024 x 1024 的应用图标的图片</li>
</ol>
<h2 id="app启动图片适配">App启动图片适配</h2>
<p>相信有一部分道友的APP在iPhone X上运行时并没有像想象中那样占满整个屏幕, 而是保持着原有的高度 在屏幕中心位置, 针对这个问题 目前经过实验得出可以通过以下方式使APP按照全屏模式运行:</p>
<ol>
<li>通过LaunchScreen.storyboard方式启动</li>
<li>如果使用的是Assets中的LaunchImage, 在增加了iPhone X尺寸的图片配置后.</li>
</ol>
<p>LaunchScreen.storyboard方式不用多说, 这里说一下如何在LaunchImage中增加iPhone X尺寸的图片配置.</p>
<p>准备一张尺寸:1125 * 2436的启动图片, 移动到LaunchImage的Finder目录中, 并在LaunchImage中的Contents.json文件中增加 (注意Json格式):</p>
<pre><code class="language-json">{
    &quot;extent&quot; : &quot;full-screen&quot;,
    &quot;idiom&quot; : &quot;iphone&quot;,
    &quot;subtype&quot; : &quot;2436h&quot;,
    &quot;filename&quot; : &quot;图片名.png&quot;,
    &quot;minimum-system-version&quot; : &quot;11.0&quot;,
    &quot;orientation&quot; : &quot;portrait&quot;,
    &quot;scale&quot; : &quot;3x&quot;
}
</code></pre>
<p>iOS 11为UIView增加了两个新的属性safeAreaInsets和safeAreaLayoutGuide, 通过这两个属性我们可以获得安全区域的范围, 通过上图可以很清楚的看到安全区域的范围, 我们要做的是让那些不能被遮挡的内容和控件在安全区域范围内显示, 注意!这句话非常重要.</p>
<ul>
<li>safeAreaInsets 适用于手动计算.</li>
<li>safeAreaLayoutGuide 适用于自动布局.</li>
</ul>
<h2 id="uinavigation">UINavigation</h2>
<ol>
<li>
<p>大标题</p>
<p>在UI navigation bar中新增了一个BOOL属性prefersLargeTitles,将该属性设置为ture，navigation bar就会在整个APP中显示大标题，如果想要在控制不同页面大标题的显示，可以通过设置当前页面的navigationItem的largeTitleDisplayMode属性；</p>
<pre><code class="language-objc">if (@available(iOS 11.0, *)) {
        self.navigationController.navigationBar.prefersLargeTitles = YES;
}
</code></pre>
<figure data-type="image" tabindex="1"><img src="http://outiw4np3.bkt.clouddn.com/b4814514cb2f3e3b4ca3bd04b131dba6.jpg" alt="" loading="lazy"></figure>
</li>
<li>
<p>titleView引入自动布局</p>
<p>会导致titleView变形，只需要在自定义view中实现<code>intrinsicContentSize </code>方法</p>
<pre><code class="language-objc">- (CGSize)intrinsicContentSize {
    return UILayoutFittingExpandedSize;
}
</code></pre>
</li>
<li>
<p>加入<code>searchController</code>属性</p>
<p>把你的UISearchController赋值给navigationItem，就可以实现将UISearchController集成到Navigation。</p>
<pre><code class="language-objc">if (@available(iOS 11.0, *)) {
    self.navigationItem.searchController = self.searchController;
    self.navigationItem.hidesSearchBarWhenScrolling = YES;
}else{
    self.searchController.searchBar.bounds = CGRectMake(0, 0, self.view.frame.size.width, 44);
    self.tableView.tableHeaderView = self.searchController.searchBar;
    [self.tableView setContentOffset:CGPointMake(0, 44)];
}
</code></pre>
<figure data-type="image" tabindex="2"><img src="http://outiw4np3.bkt.clouddn.com/fab08ab5005d661bda069710de20b8c7.jpg" alt="" loading="lazy"></figure>
</li>
</ol>
<h2 id="uitableview">UITableView</h2>
<ol>
<li>
<p>在iOS 11中默认启用Self-Sizing</p>
<p>这个应该是UITableView最大的改变。我们知道在iOS8引入Self-Sizing 之后，我们可以通过实现estimatedRowHeight相关的属性来展示动态的内容，实现了estimatedRowHeight属性后，得到的初始contenSize是个估算值，是通过estimatedRowHeight x cell的个数得到的，并不是最终的contenSize，tableView就不会一次性计算所有的cell的高度了，只会计算当前屏幕能够显示的cell个数再加上几个，滑动时，tableView不停地得到新的cell，更新自己的contenSize，在滑到最后的时候，会得到正确的contenSize。</p>
<p>Self-Sizing在iOS11下是默认开启的，Headers, footers, and cells都默认开启Self-Sizing，所有estimated 高度默认值从iOS11之前的 0 改变为UITableViewAutomaticDimension。</p>
<p>iOS11下不想使用Self-Sizing的话，可以通过以下方式关闭：（前言中提到的问题也是通过这种方式解决的）</p>
<pre><code class="language-objc">self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
</code></pre>
</li>
</ol>
<h2 id="uiviewcontroller">UIViewController</h2>
<ol>
<li>
<p><code>automaticallyAdjustsScrollViewInsets</code> &amp;&amp; <code>contentInsetAdjustmentBehavior</code></p>
<blockquote>
<p>在iOS 11之前，由于<code>UIViewController</code>的<code>automaticallyAdjustsScrollViewInsets = true</code>，在UI布局时，会出现界面中的第一个scrollView控件中的内容向下偏移64px。所以部分开发者会在开始UI布局时会将将<code>automaticallyAdjustsScrollViewInsets = false</code>。</p>
</blockquote>
<blockquote>
<p>而在iOS 11直接废除了这个属性，而在<code>UIScrollView</code>中添加了<code>contentInsetAdjustmentBehavior</code>属性来计算<code>adjustedContentInset </code>的范围。<code>adjustContentInset</code>表示<code>contentView.frame.origin</code>偏移了<code>scrollview.frame.origin</code>多少；</p>
</blockquote>
<pre><code class="language-objc">/*
如果scrollview在一个automaticallyAdjustsScrollViewContentInset = YES的controller上，
并且这个Controller包含在一个navigation controller中，
这种情况下会设置在top &amp; bottom上 adjustedContentInset = safeAreaInset + contentInset不管是否滚动。
其他情况下与UIScrollViewContentInsetAdjustmentScrollableAxes相同
*/ 
UIScrollViewContentInsetAdjustmentAutomatic, 
</code></pre>
<pre><code class="language-objc">/*
在可滚动方向上adjustedContentInset = safeAreaInset + contentInset，
在不可滚动方向上adjustedContentInset = contentInset；
依赖于scrollEnabled和alwaysBounceHorizontal / vertical = YES，scrollEnabled默认为yes，
所以大多数情况下，计算方式还是adjustedContentInset = safeAreaInset + contentInset
*/ 
UIScrollViewContentInsetAdjustmentScrollableAxes, 
</code></pre>
<pre><code class="language-objc">/*
不计算内边距,adjustedContentInset = contentInset
*/ 
UIScrollViewContentInsetAdjustmentNever, 
</code></pre>
<pre><code class="language-objc">/*
根据safeAreaInsets 计算内边距,adjustedContentInset = safeAreaInset + contentInset
*/ 
UIScrollViewContentInsetAdjustmentAlways, 
</code></pre>
</li>
</ol>
<h1 id="iphone-x-在push时tabbar上移">iPhone X 在push时TabBar上移</h1>
<h2 id="总结">总结</h2>
<p>在iOS 11发布了不久后，APP适配iOS 11和iPhone X也是踩坑不少，把自己遇到过的坑记录下来，和大家一起分享。</p>
<p>参考文章：</p>
<p><a href="http://www.cocoachina.com/ios/20171011/20737.html">iOS11、iPhone X、Xcode9 适配指南</a></p>
<p><a href="http://www.10tiao.com/html/330/201707/2653579210/1.html">你可能需要为你的 APP 适配 iOS 11</a></p>
<p><a href="https://www.lee1994.com/guan-yu-iphone/">关于iPhone X 的适配</a></p>

            </div>
            
            
              <div class="next-post">
                <div class="next">下一篇</div>
                <a href="https://tingke.gitee.io/post/post/iphone-x-hu-jiao-she-ji-guan-fang-zhi-nan/">
                  <h3 class="post-title">
                    iPhone X互交设计官方指南
                  </h3>
                </a>
              </div>
            

            

          </div>

        </div>
      </div>
    </div>

    <script src="https://unpkg.com/aos@next/dist/aos.js"></script>

<script type="application/javascript">

AOS.init();

hljs.initHighlightingOnLoad()

var app = new Vue({
  el: '#app',
  data: {
    menuVisible: false,
  },
})

</script>




  </body>
</html>
